#include "logicmgr.h"
#include "global.h"
#include <QDebug>
#include "tcpclient.h"
#include <QDateTime>
#include <QFile>
#include <QJsonDocument>

LogicMgr::~LogicMgr()
{
    _work_thread->quit();
    _work_thread->wait();
    _work_thread->deleteLater();
    _worker->deleteLater();
}

std::shared_ptr<QFileInfo> LogicMgr::GetFileInfo(QString md5)
{
    std::lock_guard<std::mutex> lock(_map_mtx);
    auto iter = _map_md5_file_info.find(md5);
    if(iter == _map_md5_file_info.end()){
        return nullptr;
    }

    return iter.value();
}

void LogicMgr::AddMD5File(QString md5, std::shared_ptr<QFileInfo> fileInfo)
{
    std::lock_guard<std::mutex> lock(_map_mtx);
    _map_md5_file_info.insert(md5,fileInfo);
}

LogicMgr::LogicMgr():QObject(nullptr)
{
    _worker = new LogicWorker();
    _work_thread = new QThread(this);
    //worker移动到子线程处理消息
    _worker->moveToThread(_work_thread);

    //连接信号和槽函数
    connect(this, &LogicMgr::sig_logic_process, _worker,
            &LogicWorker::slot_logic_process);
    connect(_worker, &LogicWorker::sig_trans_size,
            this, &LogicMgr::sig_trans_size);
    //启动线程
    _work_thread->start();

    _b_pause = false;
}

void LogicMgr::SetPause(bool pause)
{
    _b_pause = pause;
}

bool LogicMgr::Pause()
{
    return _b_pause;
}

LogicWorker::LogicWorker(QObject* parent):QObject(parent)
{
    InitHandlers();
}

void LogicWorker::InitHandlers()
{
    //注册测试消息
    _handlers[ID_TEST_MSG_RSP] = [this](QJsonObject obj){
        auto err = obj["error"].toInt();
        if(err != RSP_SUCCESS){
            qDebug() << "test msg rsp err is " << err;
            return;
        }

        auto data = obj["data"].toString();
        qDebug() << "recv data is " << data;
    };

    //注册上传消息
    _handlers[ID_UPLOAD_FILE_RSP] = [this](QJsonObject obj){
        auto err = obj["error"].toInt();
        if(err != RSP_SUCCESS){
            qDebug() << "upload msg rsp err is " << err;
            return;
        }

        auto name = obj["name"].toString();
        auto total_size = obj["total_size"].toInt();
        auto trans_size = obj["trans_size"].toInt();
        auto md5 = obj["md5"].toString();
        auto seq = obj["seq"].toInt();

        qDebug() << "recv : " << name << " file trans_size is " << trans_size;
        emit sig_trans_size(trans_size);

        //判断trans_size是否和total_size相等
        if(total_size == trans_size){
            return;
        }

        auto file_info = LogicMgr::Inst()->GetFileInfo(md5);
        if(!file_info){
            return;
        }
        //再次组织数据发送
        QFile file(file_info->filePath());
        if (!file.open(QIODevice::ReadOnly)) {
            qWarning() << "Could not open file:" << file.errorString();
            return;
        }

        //文件偏移到已经发送的位置，继续读取发送
        file.seek(trans_size);

        if(LogicMgr::Inst()->Pause()){
            return ;
        }
        QByteArray buffer;
        seq++;
        //每次读取2048字节发送
        buffer = file.read(MAX_FILE_LEN);
        QJsonObject jsonObj;
        // 将文件内容转换为 Base64 编码（可选）
        QString base64Data = buffer.toBase64();

        jsonObj["md5"] = md5;
        jsonObj["name"] = file_info->fileName();
        jsonObj["seq"] = seq;
        jsonObj["trans_size"] = buffer.size() + (seq-1)*MAX_FILE_LEN;
        jsonObj["total_size"] = total_size;

        if(buffer.size() + (seq-1)*MAX_FILE_LEN == total_size){
            jsonObj["last"] = 1;
        }else{
            jsonObj["last"] = 0;
        }

        jsonObj["data"]= base64Data;
        jsonObj["last_seq"] = obj["last_seq"].toInt();
        QJsonDocument doc(jsonObj);
        auto send_data = doc.toJson();
        TcpClient::Inst().sendMsg(ID_UPLOAD_FILE_REQ, send_data);

        file.close();
    };

    _handlers[ID_SYNC_FILE_RSP] = [this](QJsonObject obj){
        auto err = obj["error"].toInt();
        if(err != RSP_SUCCESS){
            qDebug() << " msg rsp err is " << err;
            return;
        }

        auto md5 = obj["md5"].toString();
        auto seq = obj["seq"].toInt();
        auto total_size = obj["total_size"].toInt();

        auto file_info = LogicMgr::Inst()->GetFileInfo(md5);
        if(!file_info){
            qDebug() << "not found file" ;
            return;
        }

        //再次组织数据发送
        QFile file(file_info->filePath());
        if (!file.open(QIODevice::ReadOnly)) {
            qWarning() << "Could not open file:" << file.errorString();
            return;
        }

        auto trans_size = obj["trans_size"].toInt();

        //文件偏移到已经发送的位置，继续读取发送
        file.seek(trans_size);

        if(LogicMgr::Inst()->Pause()){
            return ;
        }
        QByteArray buffer;
        seq++;
        //每次读取2048字节发送
        buffer = file.read(MAX_FILE_LEN);
        QJsonObject jsonObj;
        // 将文件内容转换为 Base64 编码（可选）
        QString base64Data = buffer.toBase64();

        jsonObj["md5"] = md5;
        jsonObj["name"] = file_info->fileName();
        jsonObj["seq"] = seq;
        jsonObj["trans_size"] = buffer.size() + (seq-1)*MAX_FILE_LEN;
        jsonObj["total_size"] = total_size;

        if(buffer.size() + (seq-1)*MAX_FILE_LEN == total_size){
            jsonObj["last"] = 1;
        }else{
            jsonObj["last"] = 0;
        }

        jsonObj["data"]= base64Data;
        jsonObj["last_seq"] = obj["last_seq"].toInt();
        QJsonDocument doc(jsonObj);
        auto send_data = doc.toJson();
        TcpClient::Inst().sendMsg(ID_UPLOAD_FILE_REQ, send_data);

        file.close();
    };
}

void LogicWorker::slot_logic_process(quint16 msgid, QJsonObject obj)
{
    if(!_handlers.contains(msgid)){
        qDebug() << "msgid: " << msgid << " not found";
        return;
    }
    _handlers[msgid](obj);
}


